// Decompiled by DJ v3.11.11.95 Copyright 2009 Atanas Neshkov  Date: 1/30/2010 10:59:11 PM
// Home Page: http://members.fortunecity.com/neshkov/dj.html  http://www.neshkov.com/dj.html - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   UFMazeGenerator.java

import java.util.Random;

public class UFMazeGenerator
    implements MazeGenerator
{

    public UFMazeGenerator()
    {
    }

    public Maze generateMaze(int i, int j, MazeGeneratorListener mazegeneratorlistener)
    {
        Random random = new Random();
        cells = new long[i][j];
        count = new int[i][j];
        for(int k = 0; k < i; k++)
        {
            for(int l = 0; l < j; l++)
            {
                cells[k][l] = makePosition(k, l);
                count[k][l] = 1;
            }

        }

        int i1 = i * j;
        MazeImpl mazeimpl = new MazeImpl(i, j);
        mazegeneratorlistener.startingMazeGeneration(mazeimpl);
        while(i1 > 1) 
        {
            boolean flag = random.nextBoolean();
            if(flag)
            {
                int j1 = random.nextInt(i - 1) + 1;
                int l1 = random.nextInt(j);
                long l2 = makePosition(j1 - 1, l1);
                long l4 = makePosition(j1, l1);
                if(FIND(l2) != FIND(l4))
                {
                    UNION(l2, l4);
                    i1--;
                    mazeimpl.removeWallWestOf(j1, l1);
                    mazegeneratorlistener.mazeModified(mazeimpl);
                }
            } else
            {
                int k1 = random.nextInt(i);
                int i2 = random.nextInt(j - 1) + 1;
                long l3 = makePosition(k1, i2 - 1);
                long l5 = makePosition(k1, i2);
                if(FIND(l3) != FIND(l5))
                {
                    UNION(l3, l5);
                    i1--;
                    mazeimpl.removeWallNorthOf(k1, i2);
                    mazegeneratorlistener.mazeModified(mazeimpl);
                }
            }
        }
        return mazeimpl;
    }

    private static int getX(long l)
    {
        long l1 = l >> 32;
        return (int)l1;
    }

    private static int getY(long l)
    {
        return (int)l;
    }

    private static long makePosition(int i, int j)
    {
        long l = i;
        long l1 = j;
        long l2 = l;
        l2 <<= 32;
        l2 += l1;
        return l2;
    }

    private long FIND(long l)
    {
        if(cells[getX(l)][getY(l)] != l)
            cells[getX(l)][getY(l)] = FIND(cells[getX(l)][getY(l)]);
        return cells[getX(l)][getY(l)];
    }

    private void UNION(long l, long l1)
    {
        long l2 = FIND(l);
        long l3 = FIND(l1);
        if(count[getX(l2)][getY(l2)] > count[getX(l3)][getY(l3)])
        {
            cells[getX(l3)][getY(l3)] = l2;
            count[getX(l2)][getY(l2)] += count[getY(l2)][getY(l3)];
        } else
        {
            cells[getX(l2)][getY(l2)] = l3;
            count[getX(l3)][getY(l3)] += count[getY(l2)][getY(l2)];
        }
    }

    private long cells[][];
    private int count[][];
}
